package com.jmb.api.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jmb.api.common.constant.RedisConstant;
import com.jmb.api.common.exception.LeaseException;
import com.jmb.api.common.result.ResultCodeEnum;
import com.jmb.api.common.utils.JwtUtil;
import com.jmb.api.common.utils.ValidUtil;
import com.jmb.api.mapper.PermissionMapper;
import com.jmb.api.model.entity.Role;
import com.jmb.api.model.entity.User;
import com.jmb.api.model.enums.BaseStatus;
import com.jmb.api.service.UserLoginLogService;
import com.jmb.api.service.UserService;
import com.jmb.api.mapper.UserMapper;
import com.jmb.api.vo.login.LoginVo;
import com.jmb.api.vo.system.UserLoginLogDao;
import com.jmb.api.vo.user.UserInfoVo;
import com.jmb.api.vo.user.UserUpdateVo;
import com.jmb.api.vo.user.UserVo;
import io.jsonwebtoken.Claims;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.w3c.dom.ls.LSException;

import java.awt.desktop.QuitResponse;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

import static net.sf.jsqlparser.util.validation.metadata.NamedObject.user;

/**
* @author jinbo
* @description 针对表【user】的数据库操作Service实现
* @createDate 2025-04-08 13:53:56
*/

@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
    implements UserService{
    @Autowired
    private ValidUtil validUtil;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private PermissionMapper permissionMapper;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private UserLoginLogService userLoginLogService;
    @Override
    public void createUser(UserVo userVo) {
        validUtil.checkName(userVo.getUsername(),"用户名不能为空");
        validUtil.checkName(userVo.getPassword(),"密码不能为空");
        validUtil.checkName(userVo.getName(),"昵称不能为空");
        validUtil.checkId(userVo.getSex());
        validUtil.checkId(userVo.getRoleId());
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUsername,userVo.getUsername());
        if (this.count(queryWrapper)>0){
            throw new LeaseException(ResultCodeEnum.WEB_API_NAME);
        }
        User user = new User();
        // 密码加密
        userVo.setPassword(DigestUtils.md5Hex(userVo.getPassword()));
        // 默认是启用状态
        userVo.setEnable(1);
        BeanUtils.copyProperties(userVo,user);
        this.save(user);
    }

    @Override
    public void updateUser(UserUpdateVo userUpdateVo) {
        validUtil.checkName(userUpdateVo.getUsername(),"用户名不能为空");
        validUtil.checkName(userUpdateVo.getName(),"昵称不能为空");
        validUtil.checkId(userUpdateVo.getSex());
        validUtil.checkId(userUpdateVo.getRoleId());

        if (userUpdateVo.getUsername()!=null){
            LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(User::getUsername,userUpdateVo.getUsername()).ne(User::getUserId,userUpdateVo.getUserId());
            if (this.count(wrapper)>0){
                throw new LeaseException(ResultCodeEnum.WEB_API_NAME);
            }
        }

        LambdaUpdateWrapper<User> queryWrapper = new LambdaUpdateWrapper<>();
        queryWrapper.eq(User::getUserId,userUpdateVo.getUserId());
        User user = new User();
        BeanUtils.copyProperties(userUpdateVo,user);
        this.update(user,queryWrapper);

    }

    @Override
    public IPage<UserInfoVo> getPageUserList(IPage<UserInfoVo> page, UserInfoVo userInfo) {
        validUtil.checkPage(page.getCurrent(),page.getSize());
        return userMapper.getListUser(page,userInfo);
    }

    @Override
    public void resetPassword(Integer id) {
        LambdaUpdateWrapper<User> queryWrapper = new LambdaUpdateWrapper<>();
        queryWrapper.eq(User::getUserId,id);
        User user = new User();
        user.setPassword(DigestUtils.md5Hex("123456"));
        this.update(user,queryWrapper);
    }

    @Override
    public HashMap<String,Object> login(LoginVo loginVo, HttpServletRequest request) {
        User user = userMapper.selectOneByLoginName(loginVo.getUsername());
        List<String> permissionList = permissionMapper.PermissionList(user.getRoleId());
        if (user ==null){
            throw new LeaseException(ResultCodeEnum.ADMIN_ACCOUNT_NOT_EXIST_ERROR);
        }
        // 0是禁用 1是启用
        if(user.getEnable() == 0){
            throw new LeaseException(ResultCodeEnum.ADMIN_ACCOUNT_DISABLED_ERROR);
        }
        if (!user.getPassword().equals(DigestUtils.md5Hex(loginVo.getPassword()))){
            throw new LeaseException(ResultCodeEnum.ADMIN_ACCOUNT_ERROR);
        }
        String token = JwtUtil.createToken(user.getUserId(), user.getUsername());
        HashMap<String , Object> map = new HashMap<>();
        map.put("token",token);
        map.put("username",user.getUsername());
        map.put("name",user.getName());
        map.put("enable",user.getEnable());
        map.put("userId",user.getUserId());
        map.put("permissionList",permissionList);
        String key = RedisConstant.USER_LOGIN_KEY+ user.getUserId();
        redisTemplate.opsForValue().set(key,token,RedisConstant.USER_LOGIN_TOKEN_TTL_SEC, TimeUnit.SECONDS);
        UserLoginLogDao userLoginLogDao = new UserLoginLogDao();
        userLoginLogDao.setUserId(user.getUserId());
        userLoginLogDao.setUsername(user.getUsername());
        userLoginLogDao.setIp(userLoginLogService.getUserIp(request));
        userLoginLogDao.setLoginTime(new Date());
        userLoginLogService.insertLoginLog(userLoginLogDao);
        return map;
    }

    @Override
    public void logout(String token) {
        Claims claims = JwtUtil.parseToken(token);
        redisTemplate.delete(RedisConstant.USER_LOGIN_KEY+claims.get(RedisConstant.USER_USERID_KEY));

    }



}




